package pixelwaks.plugins;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;

import common.ctrl.IObserver;
import common.gui.IViewable;
import common.plugin.IGameMode;

import pixelwaks.core.impl.Explosion;
import pixelwaks.core.impl.Game;
import pixelwaks.ctrl.ControlFactory;
import pixelwaks.ctrl.impl.ExplosionCtrl;
import pixelwaks.ctrl.impl.SceneryCtrl;
import pixelwaks.ctrl.impl.WindCtrl;

public abstract class GameMode implements IObserver, IGameMode {

	public final List<IViewable> observers = new ArrayList<IViewable>();
	private Object gameOverInfo;
	
	public abstract boolean isGameOver();
	
	public abstract boolean projectileHitSomething(Point p);
	
	public abstract void otherHitByExplosion(Point p, int strength);
		
	public void switchPlayer() {
		
		if(!isGameOver()) {

			if(Game.CURRENT_PLAYER < Game.getInstance().getPlayers().size()-1)
				Game.CURRENT_PLAYER++;
			else
				Game.CURRENT_PLAYER = 0;

			while(!(Game.getInstance().getCurrentPlayer().getStatus() > 0)) {
				if(Game.CURRENT_PLAYER < Game.getInstance().getPlayers().size()-1)
					Game.CURRENT_PLAYER++;
				else
					Game.CURRENT_PLAYER = 0;		
			}
			updateView();
		} else {
			try {
				Game.lock.acquire();
				Object[] options = {"Ok"};
				int chose = JOptionPane.showOptionDialog(null, gameOverInfo, 
						"Game Over", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);

				if(chose == 0) {
					System.exit(0);
				}

			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

	}
	
	public void hitByExplosion(Point p, int strength) {
		
		SceneryCtrl sctrl = (SceneryCtrl) ControlFactory.getObserver(ControlFactory.SCENERY_CTRL);
		sctrl.checkIfGotHit(p, strength);
		otherHitByExplosion(p, strength);
	}
	
	@Override
	public final void addView(IViewable iv) {
		
		observers.add(iv);
	}
	
	public final void setGameOverInfo(String str) {
		
		gameOverInfo = str;
	}
	
	public final void nextPlayer() {
		
		switchPlayer();
		WindCtrl wc = (WindCtrl) ControlFactory.getObserver(ControlFactory.WIND_CTRL);
		wc.updateWind();
	}
	
	public final void explode(Point p) {
		
		int strength = Game.getInstance().getCurrentPlayer().getCurrentWeapon().getStrength();
		hitByExplosion(p, strength);      
		ExplosionCtrl ectrl = (ExplosionCtrl) ControlFactory.getObserver(ControlFactory.EXPLOSION_CTRL);
		ectrl.startAnimation((Explosion) Game.getInstance().getExplosion(), p);
	}
	
	public final void updateView() {
	
		for (IViewable observer : observers)
			observer.updateView(null);
	}
}
